//
//  UIView+SGExtension.m
//  SGExtensionObjC
//
//  Created by xyanl on 2025/9/9.
//

#import "UIView+SGExtension.h"
#import <objc/runtime.h>

static char const * const SGKeyboardObserversKey = "SGKeyboardObserversKey";
static char kRoundedCornersShapeLayerKey;

@implementation UIView (SGExtension)

#pragma mark - Frame

-(void)setSg_x:(CGFloat)sg_x {
    CGRect frame = self.frame;
    frame.origin.x = sg_x;
    self.frame = frame;
}

- (CGFloat)sg_x {
    return self.frame.origin.x;
}


- (void)setSg_y:(CGFloat)sg_y {
    CGRect frame = self.frame;
    frame.origin.y = sg_y;
    self.frame = frame;
}

- (CGFloat)sg_y {
    return self.frame.origin.y;
}


- (void)setSg_width:(CGFloat)sg_width {
    CGRect frame = self.frame;
    frame.size.width = sg_width;
    self.frame = frame;
}

- (CGFloat)sg_width {
    return self.frame.size.width;
}


- (void)setSg_height:(CGFloat)sg_height {
    CGRect frame = self.frame;
    frame.size.height = sg_height;
    self.frame = frame;
}

- (CGFloat)sg_height {
    return self.frame.size.height;
}


- (void)setSg_centerX:(CGFloat)sg_centerX {
    CGPoint center = self.center;
    center.x = sg_centerX;
    self.center = center;
}

- (CGFloat)sg_centerX {
    return self.center.x;
}


- (void)setSg_centerY:(CGFloat)sg_centerY {
    CGPoint center = self.center;
    center.y = sg_centerY;
    self.center = center;
}

- (CGFloat)sg_centerY {
    return self.center.y;
}


- (void)setSg_size:(CGSize)sg_size {
    CGRect frame = self.frame;
    frame.size = sg_size;
    self.frame = frame;
}

- (CGSize)sg_size {
    return self.frame.size;
}


- (void)setSg_origin:(CGPoint)sg_origin {
    CGRect frame = self.frame;
    frame.origin = sg_origin;
    self.frame = frame;
}

- (CGPoint)sg_origin {
    return self.frame.origin;
}


- (CGFloat)sg_right {
    return self.frame.origin.x+self.frame.size.width;
}

-(void)setSg_right:(CGFloat)sg_right {
    CGRect frame = self.frame;
    frame.origin.x = sg_right - frame.size.width;
    self.frame = frame;
}

- (CGFloat)sg_bottom {
    return self.frame.origin.y+self.frame.size.height;
}

-(void)setSg_bottom:(CGFloat)sg_bottom {
    CGRect frame = self.frame;
    frame.origin.y = sg_bottom - frame.size.height;
    self.frame = frame;
}


/**
 * 从与当前类同名的 xib 文件加载视图
 *
 * @return 新创建的视图实例，如果加载失败则返回 nil
 */
+ (instancetype)sg_viewFromNib {
    NSString *className = NSStringFromClass(self);
    NSBundle *bundle = [NSBundle bundleForClass:self];
    
    // 检查 xib 文件是否存在
    if (![bundle pathForResource:className ofType:@"nib"]) {
        NSLog(@"⚠️ Warning: Could not find nib file named '%@' in bundle", className);
        return nil;
    }
    
    // 安全加载 xib 文件
    NSArray *nibObjects = [bundle loadNibNamed:className owner:nil options:nil];
    if (nibObjects.count == 0) {
        NSLog(@"⚠️ Warning: Failed to load objects from nib file '%@'", className);
        return nil;
    }
    
    // 类型安全检查
    id view = nibObjects.lastObject;
    if (![view isKindOfClass:self]) {
        NSLog(@"⚠️ Warning: Expected class '%@' but got '%@' from nib file", NSStringFromClass(self), NSStringFromClass([view class]));
        return nil;
    }
    
    return view;
}

/**
 * 通过遍历响应者链，查找并返回当前视图所属的视图控制器。
 * 此方法利用UIResponder的nextResponder属性向上查找，直到找到UIViewController实例。
 *
 * @return 当前视图所属的视图控制器，如果未找到则返回nil。
 */
- (UIViewController *)sg_viewController {
    UIResponder *responder = self;
    while (responder != nil) {
        if ([responder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)responder;
        }
        responder = responder.nextResponder;
    }
    return nil;
}

- (void)sg_removeAllSubviews {
    [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}

/// view 转换成 图片
- (UIImage*)sg_snapshotImage {
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size];
    return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    }];
}


#pragma mark - UIGestureRecognizer
/// 添加点击手势
- (UITapGestureRecognizer *)sg_addTapGestureWithTarget:(id)target action:(nullable SEL)selector {
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:target action:selector];
    [self addGestureRecognizer:tap];
    return tap;
}

/// 添加长按手势
- (UILongPressGestureRecognizer *)sg_addLongPressGestureWithTarget:(id)target action:(nullable SEL)selector {
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:target action:selector];
    [self addGestureRecognizer:longPress];
    return longPress;
}

/// 添加拖拽手势
- (UIPanGestureRecognizer *)sg_addPanGestureWithTarget:(id)target action:(nullable SEL)selector {
    UIPanGestureRecognizer *panPress = [[UIPanGestureRecognizer alloc] initWithTarget:target action:selector];
    [self addGestureRecognizer:panPress];
    return panPress;
}

#pragma mark - 圆角

- (void)sg_addRoundedCornersRadius:(CGFloat)cornerRadius {
    [self layoutIfNeeded]; // 确保frame已更新
    [self sg_addRoundedCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(cornerRadius, cornerRadius) frame:self.bounds];
}

- (void)sg_addRoundedCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii {
    [self layoutIfNeeded]; // 确保frame已更新
    [self sg_addRoundedCorners:corners cornerRadii:cornerRadii frame:self.bounds];
}

- (void)sg_addRoundedCorners:(UIRectCorner)corners
                 cornerRadii:(CGSize)cornerRadii
                       frame:(CGRect)frame {
    [self _applyRoundedCorners:corners
                   cornerRadii:cornerRadii
                         frame:frame
                      animated:NO
                      duration:0];
}

- (void)sg_addRoundedCorners:(UIRectCorner)corners
                 cornerRadii:(CGSize)cornerRadii
           animationDuration:(NSTimeInterval)duration {
    [self layoutIfNeeded]; // 确保frame已更新
    [self _applyRoundedCorners:corners
                   cornerRadii:cornerRadii
                         frame:self.bounds
                      animated:YES
                      duration:duration];
}

- (void)sg_removeRoundedCorners {
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.layer.mask = nil;
    [CATransaction commit];
    
    objc_setAssociatedObject(self, &kRoundedCornersShapeLayerKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)sg_hasRoundedCorners {
    return [self.layer.mask isKindOfClass:[CAShapeLayer class]];
}

/// 为视图设置自定义圆角
/// - Parameters:
///   - topLeft: 左上角半径
///   - topRight: 右上角半径
///   - bottomLeft: 左下角半径
///   - bottomRight: 右下角半径
- (void)sg_addCornerRadiusWithTopLeft:(CGFloat)topLeft
                             topRight:(CGFloat)topRight
                           bottomLeft:(CGFloat)bottomLeft
                          bottomRight:(CGFloat)bottomRight {
    
    // 确保在布局完成后执行
    dispatch_async(dispatch_get_main_queue(), ^{
        UIBezierPath *maskPath = [UIBezierPath bezierPath];
        CGRect bounds = self.bounds;
        CGFloat width = CGRectGetWidth(bounds);
        CGFloat height = CGRectGetHeight(bounds);
        
        // 开始路径
        [maskPath moveToPoint:CGPointMake(0, topLeft)];
        
        // 左上角圆弧
        if (topLeft > 0) {
            [maskPath addArcWithCenter:CGPointMake(topLeft, topLeft)
                                radius:topLeft
                            startAngle:M_PI
                              endAngle:M_PI * 3 / 2
                             clockwise:YES];
        } else {
            [maskPath addLineToPoint:CGPointMake(0, 0)];
        }
        
        // 顶部线
        [maskPath addLineToPoint:CGPointMake(width - topRight, 0)];
        
        // 右上角圆弧
        if (topRight > 0) {
            [maskPath addArcWithCenter:CGPointMake(width - topRight, topRight)
                                radius:topRight
                            startAngle:M_PI * 3 / 2
                              endAngle:0
                             clockwise:YES];
        } else {
            [maskPath addLineToPoint:CGPointMake(width, 0)];
        }
        
        // 右侧线
        [maskPath addLineToPoint:CGPointMake(width, height - bottomRight)];
        
        // 右下角圆弧
        if (bottomRight > 0) {
            [maskPath addArcWithCenter:CGPointMake(width - bottomRight, height - bottomRight)
                                radius:bottomRight
                            startAngle:0
                              endAngle:M_PI / 2
                             clockwise:YES];
        } else {
            [maskPath addLineToPoint:CGPointMake(width, height)];
        }
        
        // 底部线
        [maskPath addLineToPoint:CGPointMake(bottomLeft, height)];
        
        // 左下角圆弧
        if (bottomLeft > 0) {
            [maskPath addArcWithCenter:CGPointMake(bottomLeft, height - bottomLeft)
                                radius:bottomLeft
                            startAngle:M_PI / 2
                              endAngle:M_PI
                             clockwise:YES];
        } else {
            [maskPath addLineToPoint:CGPointMake(0, height)];
        }
        
        // 闭合路径
        [maskPath closePath];
        
        // 创建形状图层
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    });
}

#pragma mark - Private Methods

- (void)_applyRoundedCorners:(UIRectCorner)corners
                 cornerRadii:(CGSize)cornerRadii
                       frame:(CGRect)frame
                    animated:(BOOL)animated
                    duration:(NSTimeInterval)duration {
    // 参数检查
    if (CGRectIsNull(frame) || CGRectIsEmpty(frame)) {
        NSLog(@"Warning: Invalid frame provided for rounded corners");
        return;
    }
    
    // 获取或创建shape layer
    CAShapeLayer *shapeLayer = [self _roundedCornersShapeLayer];
    if (!shapeLayer) {
        shapeLayer = [CAShapeLayer layer];
        objc_setAssociatedObject(self, &kRoundedCornersShapeLayerKey, shapeLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    // 创建圆角路径
    UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:frame
                                                      byRoundingCorners:corners
                                                            cornerRadii:cornerRadii];
    
    // 配置shape layer
    shapeLayer.frame = frame;
    shapeLayer.path = roundedPath.CGPath;
    
    // 设置mask（禁用隐式动画）
    [CATransaction begin];
    [CATransaction setDisableActions:!animated];
    self.layer.mask = shapeLayer;
    [CATransaction commit];
    
    // 添加动画（如果需要）
    if (animated && duration > 0) {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
        animation.fromValue = (__bridge id _Nullable)([(CAShapeLayer *)self.layer.mask path]);
        animation.toValue = (__bridge id _Nullable)(roundedPath.CGPath);
        animation.duration = duration;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [shapeLayer addAnimation:animation forKey:@"path"];
    }
}

- (CAShapeLayer *)_roundedCornersShapeLayer {
    id layer = objc_getAssociatedObject(self, &kRoundedCornersShapeLayerKey);
    return [layer isKindOfClass:[CAShapeLayer class]] ? layer : nil;
}

#pragma mark - 边框

- (void)sg_addLayerRoundedCorners:(CGFloat)cornerRadius
                      borderWidth:(CGFloat)borderWidth
                      borderColor:(UIColor *)borderColor {
    [self sg_addLayerRoundedCorners:cornerRadius borderWidth:borderWidth borderColor:borderColor animation:NO duration:0];
}

- (void)sg_addLayerRoundedCorners:(CGFloat)cornerRadius
                      borderWidth:(CGFloat)borderWidth
                      borderColor:(UIColor *)borderColor
                        animation:(BOOL)animated
                         duration:(NSTimeInterval)duration {
    // 1. 参数校验
    if (cornerRadius < 0) {
        NSLog(@"Warning: Invalid corner radius, must be >= 0");
        cornerRadius = 0;
    }
    
    if (borderWidth < 0) {
        NSLog(@"Warning: Invalid border width, must be >= 0");
        borderWidth = 0;
    }
    
    if (animated && duration > 0) {
        [UIView animateWithDuration:duration animations:^{
            [CATransaction begin];
            [CATransaction setAnimationDuration:duration];
            [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
            
            [self _applyLayerRoundedCorners:cornerRadius borderWidth:borderWidth borderColor:borderColor];
            
            [CATransaction commit];
        }];
    } else {
        [self _applyLayerRoundedCorners:cornerRadius borderWidth:borderWidth borderColor:borderColor];
    }
}

- (void)_applyLayerRoundedCorners:(CGFloat)cornerRadius
                      borderWidth:(CGFloat)borderWidth
                      borderColor:(UIColor *)borderColor {
    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = YES;
    
    if (borderWidth > 0) {
        self.layer.borderWidth = borderWidth;
        self.layer.borderColor = borderColor.CGColor;
    } else {
        self.layer.borderWidth = 0;
        self.layer.borderColor = nil;
    }
    
    self.layer.shouldRasterize = YES;
    self.layer.rasterizationScale = [UIScreen mainScreen].scale;
}

- (void)sg_removeLayerRoundedCorners {
    [self sg_addLayerRoundedCorners:0 borderWidth:0 borderColor:[UIColor whiteColor]];
}


@end
